package com.ganmiao.server.sys.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.ganmiao.exception.DefaultBusinessException;
import com.ganmiao.resp.PageResult;
import com.ganmiao.server.sys.dto.SysRoleDto;
import com.ganmiao.server.sys.entity.SysRole;
import com.ganmiao.server.sys.query.SysRoleQuery;
import com.ganmiao.server.sys.repository.SysRoleRepository;
import com.ganmiao.server.sys.vo.SysRoleVo;
import com.ganmiao.server.sys.vo.SysUserVo;
import com.ganmiao.server.user.context.UserAuthContext;
import com.ganmiao.server.user.enums.SysCodeEnum;
import com.ganmiao.utils.StatusUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotNull;
import java.util.*;

/**
 * 角色信息
 */
@Service
public class SysRoleService {

    //角色信息
    @Autowired
    private SysRoleRepository sysRoleRepository;

    //角色菜单信息
    @Autowired
    private SysRoleMenuService sysRoleMenuService;

    @Autowired
    private SysMenuService sysMenuService;

    @Autowired
    private SysUserRoleService sysUserRoleService;

    /**
     * 修改显示顺序
     *
     * @param roleSort
     * @return
     */
    public boolean updateRoleSort(Integer roleSort) {

        //获取系统编码
        String sysCode = UserAuthContext.getSysCode();

        //修改条件
        LambdaUpdateWrapper<SysRole> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SysRole::getSysCode, sysCode)
                .eq(SysRole::getStatus, StatusUtils.PASS)
                .gt(SysRole::getRoleSort, roleSort)
                .setSql("role_sort = role_sort + 1");

        return sysRoleRepository.update(updateWrapper);

    }

    /**
     * 验证角色是否存在
     *
     * @param roleName
     * @return
     */
    public boolean verifySysRoleIsExist(String roleName) {

        //获取系统编码
        String sysCode = UserAuthContext.getSysCode();

        //获取用户信息
        SysUserVo loginUser = UserAuthContext.getLoginUser();

        //查询条件
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRole::getSysCode, sysCode)
                .eq(loginUser.getSupplierId() != null, SysRole::getSupplierId, loginUser.getSupplierId())
                .eq(SysRole::getRoleName, roleName)
                .eq(SysRole::getStatus, StatusUtils.PASS);
        SysRole one = sysRoleRepository.getOne(queryWrapper);

        return !Objects.isNull(one);

    }

    /**
     * 新增角色信息
     *
     * @param sysRoleDto
     * @return
     */
    @Transactional
    public boolean addSysRole(SysRoleDto sysRoleDto) {

        //获取系统编码并赋值
        String sysCode = UserAuthContext.getSysCode();
        sysRoleDto.setSysCode(sysCode);

        //获取用户信息
        SysUserVo loginUser = UserAuthContext.getLoginUser();
        if (loginUser != null && loginUser.getSupplierId() != null) {
            sysRoleDto.setSupplierId(loginUser.getSupplierId());
        }
        if (loginUser != null && loginUser.getShopId() != null) {
            sysRoleDto.setShopId(loginUser.getShopId());
        }

        //验证同级菜单是否存在
        if (verifySysRoleIsExist(sysRoleDto.getRoleName())) {

            throw new DefaultBusinessException("角色已存在");

        }
        SysRole sysRole = new SysRole();
        BeanUtils.copyProperties(sysRoleDto, sysRole);
        //新增角色信息
        boolean save = sysRoleRepository.save(sysRole);

        //修改显示顺序
        updateRoleSort(sysRoleDto.getRoleSort());

        //新增角色菜单信息
        sysRoleMenuService.addSysRoleMenu(sysRole.getRoleId(), sysRoleDto.getMenuIdList());

        return save;

    }

    /**
     * 启用/停用/删除角色信息
     *
     * @param sysRole
     * @return
     */
    @Transactional
    public boolean deleteSysRole(SysRole sysRole) {

        //删除条件
        LambdaUpdateWrapper<SysRole> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SysRole::getRoleId, sysRole.getRoleId())
                .set(SysRole::getStatus, sysRole.getStatus());
        boolean update = sysRoleRepository.update(updateWrapper);

        //验证状态是否是删除
        if (sysRole.getStatus().equals(StatusUtils.FAILURE)) {

            //删除角色菜单信息
            sysRoleMenuService.deleteSysRoleMenuByRoleId(sysRole.getRoleId());

        }

        return update;

    }

    /**
     * 修改角色信息
     *
     * @param sysRoleDto
     * @return
     */
    @Transactional
    public boolean updateSysRole(SysRoleDto sysRoleDto) {

        //获取角色信息
        SysRole role = sysRoleRepository.getById(sysRoleDto.getRoleId());

        //验证同级菜单是否存在
        if (!role.getRoleName().equals(sysRoleDto.getRoleName()) && verifySysRoleIsExist(sysRoleDto.getRoleName())) {

            throw new DefaultBusinessException("角色已存在");

        }
        SysRole sysRole = new SysRole();
        BeanUtils.copyProperties(sysRoleDto, sysRole);
        //修改角色信息
        boolean updateById = sysRoleRepository.updateById(sysRole);

        //修改角色菜单信息
        sysRoleMenuService.updateSysRoleMenu(sysRole.getRoleId(), sysRoleDto.getMenuIdList());

        return updateById;

    }

    /**
     * 获取角色信息 (分页)
     *
     * @param sysRoleQuery
     * @return
     */
    public PageResult<SysRole> getSysRoleList(SysRoleQuery sysRoleQuery) {

        //获取系统编码
        String sysCode = UserAuthContext.getSysCode();

        //获取用户信息
        SysUserVo loginUser = UserAuthContext.getLoginUser();

        //查询条件
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRole::getSysCode, sysCode)
                .eq(loginUser.getSupplierId() != null, SysRole::getSupplierId, loginUser.getSupplierId())
                .eq(loginUser.getShopId() != null, SysRole::getShopId, loginUser.getShopId())
                .ne(SysRole::getStatus, StatusUtils.FAILURE)
                .like(StringUtils.isNotBlank(sysRoleQuery.getRoleName()), SysRole::getRoleName, sysRoleQuery.getRoleName())
                .orderByAsc(SysRole::getRoleSort);
        return sysRoleRepository.queryPage(sysRoleQuery.getPage(), sysRoleQuery.getPageSize(), queryWrapper);

    }

    /**
     * 获取角色信息 (详情)
     *
     * @param roleId
     * @return
     */
    public SysRoleVo getSysRole(@NotNull(message = "角色主键ID不能为空") Integer roleId) {

        //获取角色信息
        SysRole role = sysRoleRepository.getById(roleId);

        //返回数据
        SysRoleVo sysRoleVo = new SysRoleVo();

        //拷贝数据并获取角色菜单信息
        BeanUtils.copyProperties(role, sysRoleVo);
        List<Integer> menuIds = sysRoleMenuService.getMenuIds(roleId, "0");
        List<Integer> h5MenuIds = sysRoleMenuService.getMenuIds(roleId, "1");
        sysRoleVo.setMenuIds(menuIds);
        sysRoleVo.setH5MenuIds(h5MenuIds);
        return sysRoleVo;

    }

    /**
     * 获取角色信息 (多详情)
     *
     * @param roleIds
     * @return
     */
    public List<SysRoleVo> getSysRoleIds(List<Integer> roleIds) {

        //返回数据
        List<SysRoleVo> list = new ArrayList<>();

        //查询条件
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(!roleIds.isEmpty(), SysRole::getRoleId, roleIds)
                .eq(SysRole::getStatus, StatusUtils.PASS)
                .orderByAsc(SysRole::getRoleSort);
        //查询结果
        List<SysRole> sysRoleList = sysRoleRepository.list(queryWrapper);

        //获取角色菜单ID
        sysRoleList.forEach(item -> {

            SysRoleVo sysRoleVo = new SysRoleVo();
            BeanUtils.copyProperties(item, sysRoleVo);
            sysRoleVo.setMenuIds(sysRoleMenuService.getMenuIds(item.getRoleId(), "0"));
            sysRoleVo.setH5MenuIds(sysRoleMenuService.getMenuIds(item.getRoleId(), "1"));
            list.add(sysRoleVo);

        });

        return list;
    }

    /**
     * 创建供应商管理员
     *
     * @param supplierId
     * @param userId
     * @return
     */
    public boolean createdSupplierRole(Integer supplierId, Integer userId) {
        List<Integer> menuIds = sysMenuService.getSupplierMenuIds("0");
        List<Integer> h5MenuIds = sysMenuService.getSupplierMenuIds("1");
        SysRole sysRole = SysRole.builder()
                .sysCode(SysCodeEnum.SUPPLIER.getCode())
                .supplierId(supplierId)
                .menuIds(menuIds)
                .roleName("系统管理员")
                .roleSort(1)
                .build();

        //新增角色信息
        boolean save = sysRoleRepository.save(sysRole);

        sysUserRoleService.addSysUserRoleByUserId(userId, Arrays.asList(sysRole.getRoleId()));
        Map<String, List<Integer>> map = new HashMap<>();
        if (!menuIds.isEmpty()) {
            map.put("0", menuIds);
        }
        if (!h5MenuIds.isEmpty()) {
            map.put("1", h5MenuIds);
        }
        //新增角色菜单信息
        sysRoleMenuService.addSysRoleMenu(sysRole.getRoleId(), map);

        return save;
    }

    /**
     * 创建商超管理员
     *
     * @param shopId
     * @param userId
     * @return
     */
    public boolean createdShopRole(Integer shopId, Integer userId) {
        List<Integer> menuIds = sysMenuService.getShopMenuIds("0");
        List<Integer> h5MenuIds = sysMenuService.getShopMenuIds("1");
        SysRole sysRole = SysRole.builder()
                .sysCode(SysCodeEnum.SUPERMARKET.getCode())
                .shopId(shopId)
                .menuIds(menuIds)
                .roleName("系统管理员")
                .roleSort(1)
                .build();

        //新增角色信息
        boolean save = sysRoleRepository.save(sysRole);

        sysUserRoleService.addSysUserRoleByUserId(userId, Arrays.asList(sysRole.getRoleId()));
        Map<String, List<Integer>> map = new HashMap<>();
        if (!menuIds.isEmpty()) {
            map.put("0", menuIds);
        }
        if (!h5MenuIds.isEmpty()) {
            map.put("1", h5MenuIds);
        }
        //新增角色菜单信息
        sysRoleMenuService.addSysRoleMenu(sysRole.getRoleId(), map);

        return save;
    }

}
